package com.leboncoin.http;

import com.leboncoin.bean.ClassifiedBean;
import java.io.*;
import java.util.List;
import java.util.logging.Level;
import java.util.logging.Logger;
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.DefaultHttpClient;

/**
 * Toolbox to help retrieving HTTP content from Web pages. Acts as HTTP client.
 * @author ben
 */
public class HttpManager {

	static final Logger logger = Logger.getLogger(HttpManager.class.getName());	
    
    /**
     * Get input stream from http URI
     * @param link URI to retrieve content from
     * @return the input stream
     */
	public static InputStream getInputStream(String link){
		
		InputStream inputStream = null;
        DefaultHttpClient httpclient = new DefaultHttpClient();
		
		try{
	
	        HttpGet httpget = new HttpGet(link);
	
	        HttpResponse response = httpclient.execute(httpget);
	        HttpEntity entity = response.getEntity();
	        
	        inputStream = entity.getContent();
	        
		}catch (Exception e){
			logger.log(Level.SEVERE, "Fail to retrieve content from URI {0}", link);
			logger.severe(e.getMessage());
		}
		
		return inputStream;
	}

    /**
     * Write content from http URI to given output stream
     * @param url the URI
     * @param outputStream the output stream
     * @return true if writing is successful
     */
	public static Boolean writeContentFromUrl(String url, OutputStream outputStream){
		
		Boolean result = false;
		byte[] buffer = new byte[20000];
		InputStream inputStream = null;
 		
		try{
			inputStream = getInputStream(url);
			if (inputStream != null){
		        int byteNumber;
		        while ((byteNumber=inputStream.read(buffer))>0){
		        	outputStream.write(buffer, 0, byteNumber);
                }
	        	result = true;
			}
	        
		}catch (Exception e){
			logger.log(Level.SEVERE, "Fail to retrieve content from URI {0}", url);
			logger.severe(e.getMessage());
		}
		if (inputStream != null){
			try{
				inputStream.close();
			}catch (IOException e){
				logger.log(Level.SEVERE, "Fail to close input stream from URI {0}", url);
				logger.severe(e.getMessage());
			}
		} 
	
		return result;
	}
	
	public static File writeImageToFile(String imageLink, String fileName){
		
		File result = null;
		FileOutputStream outputStream = null;
		try{
			result = new File(fileName);
			outputStream = new FileOutputStream(result);
			if(!writeContentFromUrl(imageLink, outputStream)){
				result = null;
			}
		}catch (Exception e){
			logger.log(Level.SEVERE, "Fail to write from URI {0} to file {1}", new Object[]{imageLink, fileName});
			logger.severe(e.getMessage());
		}
		if (outputStream != null){
			try{
				outputStream.close();
			}catch (Exception e){
				logger.log(Level.SEVERE, "Fail to close file output stream for file {0}", fileName);
				logger.severe(e.getMessage());
			}
		}
		return result;
	}
	
	public static Boolean downloadClassifiedImages(List<ClassifiedBean> classifieds){
		
		Boolean result = false;
		int imageCount = 1;
		for (ClassifiedBean classifiedBean:classifieds){
			for (String imageLink:classifiedBean.getImageLinks()){
				String fileName = "c:\\temp\\leboncoin-image-"+imageCount+".jpg";
				File file = writeImageToFile(imageLink, fileName);
				if (file != null){
					classifiedBean.getImageFiles().add(file);
				}
			}
		}
		return result;
	}
	
    /**
     * Get HTML content from given url
     * @param url the URL
     * @return HTML content as string
     */
	public static String getHtmlPage(String url){
		String content = null;
		ByteArrayOutputStream outputStream = new ByteArrayOutputStream();

		if (writeContentFromUrl(url, outputStream)){
			try {
				content = outputStream.toString("UTF-8");
			}catch (UnsupportedEncodingException e){
				logger.log(Level.SEVERE, "Cannot decode page content from URL {0}", url);
				logger.severe(e.getMessage());
			}
		}
		try{
			outputStream.close();
		}catch (Exception e){
			logger.severe("Fail to close byte array output stream ");
			logger.severe(e.getMessage());
		}
		return content;
	}
}
